package testappserver;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

    //Порт, на котором слушет сервер
    private final int serverPort = 5555;
    //Время непрерывной прослушки сокетом
    private final int serverSocketTimeout = 100;
    //серверный сокет
    private ServerSocket serverSocket;
    //Списочек подключенных клиетов
    private List<SingleClient> clients;
    //Примитив синхронизации
    private Lock lock;
    //поток, в котором работает сервер
    private Thread myThread;

    //Конструктор
    public Server() throws IOException {
        serverSocket = new ServerSocket(serverPort);
        serverSocket.setSoTimeout(serverSocketTimeout);
        clients = new ArrayList<SingleClient>();
        lock = new ReentrantLock();
    }

    //Запуск сервера
    public void Start() {
        int clientNumber = 0;
        int currentNumber = 1;
        while (currentNumber != 4) {
            try {
                lock.lock();

                if (clientNumber == currentNumber - 1) {
                    clientNumber = currentNumber;
                    Main.RunClient(String.valueOf(clientNumber));
                }
                //Ждем подключения клиента
                SingleClient client = new SingleClient(serverSocket.accept());
                //Добавляем клиента
                clients.add(client);
                //Запускаем обработку клиента
                client.Connect();
                currentNumber++;
            } catch (SocketTimeoutException e) {
                //Штатный эксепшн - ничего не делаем
            } catch (IOException ex) {
                //Ошибка в сокете
                Logger.getLogger(Server.class.getName()).log(Level.SEVERE, "Connection error: ", ex);
            }
            finally {
                lock.unlock();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException ex) {
                }
            }
        }
    }

    //Остановка сервера
    public void Stop() {
        try {
            try {
                lock.lock();
                try {
                    //Ждем завершения рабочего потока
                    Thread.sleep(serverSocketTimeout);
                } catch (InterruptedException ex) { }
            } finally {
                lock.unlock();
            }
            //отключаем всех клиентов
            for (SingleClient client : clients) {
                client.Disconnect();
            }
            //закрываем сокет
            serverSocket.close();
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, "Server stop error: ", ex);
        }
    }

    public void AddCommand(int client, double value) {
        if (clients.size() != 3)
            return;
        clients.get(client).AddCommand(String.valueOf(value));
    }
}
